package com.wedimob.slideshare.video;

import java.io.InputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;

import com.google.gson.Gson;

public class JavaDailyMotionDownloader extends JavaVideoDownloader {

    private String url;

    public JavaDailyMotionDownloader(String url, String outputDir) {
        this.url = url;
        this.outputDir = outputDir;
    }

    private static class JSONResponse {
        public String sequence;
    }

    private static class JSONRes6 {
        public String ldURL;
        public String sdURL;
        public String hqURL;
        public String hd720URL;
    }

    private static class JSONRes5 {
        public JSONRes6 param;
    }

    private static class JSONRes4 {
        public List<JSONRes5> layerList;
    }

    private static class JSONRes3 {
        public List<JSONRes4> sequenceList;
    }

    private static class JSONRes2 {
        public List<JSONRes3> layerList;
    }

    private static class JSONRes1 {
        public List<JSONRes2> sequence;
    }

    @Override
    protected Map<String, String> getUrls() {
        try {
            if (info != null) {
                Map<String, String> result = new HashMap<String, String>();
                for (String quality : info.sizes.keySet()) {
                    result.put(quality, humanReadableByteCount(info.sizes.get(quality), false));
                }
                return result;
            }

            info = new VideoInfo();
            CookieStore cookieStore = new BasicCookieStore();
            info.encoding = "UTF-8";
            info.userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";
            info.videoId = url;
            info.localContext = new BasicHttpContext();
            info.localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
            info.httpclient = new DefaultHttpClient();
            info.urls = new HashMap<String, String>();

            HttpGet httpget = new HttpGet(info.videoId);
            httpget.setHeader("User-Agent", info.userAgent);
            HttpResponse response = info.httpclient.execute(httpget,
                    info.localContext);
            HttpEntity entity = response.getEntity();
            if (entity != null && response.getStatusLine().getStatusCode() == 200) {
                InputStream instream = entity.getContent();
                String videoInfo = getStringFromInputStream(info.encoding, instream);
                if (videoInfo != null && videoInfo.length() > 0) {

                    int beginIndex = videoInfo.indexOf("var flashvars = ");
                    int endIndex = videoInfo.indexOf("};", beginIndex + "var flashvars = ".length());
                    String json = videoInfo
                            .substring(beginIndex + "var flashvars = ".length(), endIndex + 1);
                    Gson gson = new Gson();
                    JSONResponse jsonObj = gson.fromJson(json, JSONResponse.class);

                    beginIndex = videoInfo.indexOf("<title>");
                    endIndex = videoInfo.indexOf("- Vidéo Dailymotion", beginIndex + 7);
                    info.title = videoInfo.substring(beginIndex + 7, endIndex - 1);

                    JSONRes1 jsonObjRes1 = gson.fromJson(URLDecoder.decode(jsonObj.sequence, "UTF-8"), JSONRes1.class);
                    for (JSONRes2 jsonObjRes2 : jsonObjRes1.sequence) {
                        for (JSONRes3 jsonObjRes3 : jsonObjRes2.layerList) {
                            for (JSONRes4 jsonObjRes4 : jsonObjRes3.sequenceList) {
                                for (JSONRes5 jsonObjRes5 : jsonObjRes4.layerList) {
                                    if (jsonObjRes5.param != null) {
                                        if (jsonObjRes5.param.ldURL != null)
                                            info.urls.put("video/mp4:small", jsonObjRes5.param.ldURL);
                                        if (jsonObjRes5.param.sdURL != null)
                                            info.urls.put("video/mp4:medium", jsonObjRes5.param.sdURL);
                                        if (jsonObjRes5.param.hqURL != null)
                                            info.urls.put("video/mp4:large", jsonObjRes5.param.hqURL);
                                        if (jsonObjRes5.param.hd720URL != null)
                                            info.urls.put("video/mp4:720p", jsonObjRes5.param.hd720URL);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            info.sizes = new HashMap<String, Integer>();
            for (String quality : info.urls.keySet()) {
                String url = info.urls.get(quality);
                info.sizes.put(quality, getFileSize(url));
            }

            Map<String, String> result = new HashMap<String, String>();
            for (String quality : info.sizes.keySet()) {
                result.put(quality, humanReadableByteCount(info.sizes.get(quality), true));
            }

            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
